﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Controls;

namespace HYView
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class SwitchView
	{
		public static Result SetUsableView(CmdViewType types, ExternalCommandData cmdData)
		{
			return SwitchView.SetUsableView(types, cmdData.Application);
		}

		public static Result SetUsableView(CmdViewType types, UIApplication app)
		{
			return SwitchView.SetUsableViewAll(types, app, false, "", false);
		}

		public static Result SetUsableView(AreaPlanType types, UIApplication app)
		{
			return SwitchView.SetUsableViewAll(types, app, false, "");
		}

		public static Result SetUsableViewSheet(CmdViewType types, UIApplication app)
		{
			return SwitchView.SetUsableViewAll(types, app, false, "", true);
		}

		public static Result SetUsableViewIncludeKeyWord(CmdViewType types, ExternalCommandData cmdData, string strIncludeKeyWord)
		{
			return SwitchView.SetUsableViewAll(types, cmdData.Application, false, strIncludeKeyWord, false);
		}

		public static Result SetUsableViewAll(CmdViewType types, ExternalCommandData cmdData, string strIncludeKeyWord = "")
		{
			return SwitchView.SetUsableViewAll(types, cmdData.Application, true, strIncludeKeyWord, false);
		}

		public static Result SetUsableViewAll(AreaPlanType types, UIApplication app, bool bIncludeCurView, string strIncludeKeyWord = "")
		{
			Autodesk.Revit.DB.View activeView = app.ActiveUIDocument.ActiveView;
			CmdViewType cmdViewType = SwitchView.RevitViewTypeToLocalViewType(activeView);
			if (!bIncludeCurView && (cmdViewType & CmdViewType.AreaPlan) != CmdViewType.Other)
			{
				if (!(strIncludeKeyWord != ""))
				{
					return Autodesk.Revit.UI.Result.Succeeded;
				}
				if (RevitVersionFuncs.GetViewName(activeView).IndexOf(strIncludeKeyWord) >= 0)
				{
					return Autodesk.Revit.UI.Result.Succeeded;
				}
			}
			List<Autodesk.Revit.DB.View> usableViews = SwitchView.GetUsableViews(SwitchView.FliterViews(app), CmdViewType.AreaPlan);
			if (strIncludeKeyWord != "")
			{
				for (int i = 0; i < usableViews.Count; i++)
				{
					if (RevitVersionFuncs.GetViewName(usableViews[i]).IndexOf(strIncludeKeyWord) < 0)
					{
						usableViews.RemoveAt(i--);
					}
				}
			}
			if (usableViews.Count == 0)
			{
				YJKMessageBox.Show("当前项目中没有该命令可用的视图。");
				return Autodesk.Revit.UI.Result.Failed;
			}
			List<string> list = new List<string>();
			List<Autodesk.Revit.DB.View> list2 = new List<Autodesk.Revit.DB.View>();
			foreach (Autodesk.Revit.DB.View view in usableViews)
			{
				ElementId typeId = view.GetTypeId();
				Element element = app.ActiveUIDocument.Document.GetElement(typeId);
				if (element != null)
				{
					string areaPlanViewName = SwitchView.GetAreaPlanViewName(types, element, view);
					if (areaPlanViewName != null)
					{
						list.Add(areaPlanViewName);
						list2.Add(view);
					}
				}
			}
			if (list.Count == 0)
			{
				YJKMessageBox.Show("当前项目中没有可用的防火分区面积视图。");
				return Autodesk.Revit.UI.Result.Failed;
			}
			SwitchViewForm switchViewForm = new SwitchViewForm(list);
			if (switchViewForm.ShowDialog() == DialogResult.OK)
			{
				app.ActiveUIDocument.ActiveView = list2[switchViewForm.SelectIndex];
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		public static Result SetUsableViewAll(CmdViewType types, UIApplication app, bool bIncludeCurView, string strIncludeKeyWord = "", bool bSheetShowNumber = false)
		{
			Autodesk.Revit.DB.View activeView = app.ActiveUIDocument.ActiveView;
			CmdViewType cmdViewType = SwitchView.RevitViewTypeToLocalViewType(activeView);
			if (!bIncludeCurView && (cmdViewType & types) != CmdViewType.Other)
			{
				if (!(strIncludeKeyWord != ""))
				{
					return Autodesk.Revit.UI.Result.Succeeded;
				}
				if (RevitVersionFuncs.GetViewName(activeView).IndexOf(strIncludeKeyWord) >= 0)
				{
					return Autodesk.Revit.UI.Result.Succeeded;
				}
			}
			List<Autodesk.Revit.DB.View> usableViews = SwitchView.GetUsableViews(SwitchView.FliterViews(app), types);
			if (strIncludeKeyWord != "")
			{
				for (int i = 0; i < usableViews.Count; i++)
				{
					if (RevitVersionFuncs.GetViewName(usableViews[i]).IndexOf(strIncludeKeyWord) < 0)
					{
						usableViews.RemoveAt(i--);
					}
				}
			}
			if (usableViews.Count == 0)
			{
				YJKMessageBox.Show("当前项目中没有该命令可用的视图。");
				return Autodesk.Revit.UI.Result.Failed;
			}
			List<string> list = new List<string>();
			foreach (Autodesk.Revit.DB.View view in usableViews)
			{
				ElementId typeId = view.GetTypeId();
				Element element = app.ActiveUIDocument.Document.GetElement(typeId);
				if (element != null)
				{
					string str = RevitVersionFuncs.GetViewName(view);
					if ((int)view.ViewType == 6 && bSheetShowNumber)
					{
						Parameter parameter = view.get_Parameter(BuiltInParameter.SHEET_NUMBER);
						if (parameter != null)
						{
							str = parameter.AsString();
						}
					}
					string item = (element as ViewFamilyType).Name + "：" + str;
					list.Add(item);
				}
			}
			SwitchViewForm switchViewForm = new SwitchViewForm(list);
			if (switchViewForm.ShowDialog() == DialogResult.OK)
			{
				app.ActiveUIDocument.ActiveView = usableViews[switchViewForm.SelectIndex];
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			return Autodesk.Revit.UI.Result.Cancelled;
		}

		public static CmdViewType RevitViewTypeToLocalViewType(Autodesk.Revit.DB.View view)
		{
			CmdViewType result = CmdViewType.Other;
			if (view == null)
			{
				return result;
			}
			ViewType viewType = view.ViewType;
            switch ((int)viewType)
			{
			case 1:
				return CmdViewType.FloorPlan;
			case 2:
				return CmdViewType.CeilingPlan;
			case 3:
				return CmdViewType.Elevation;
			case 4:
				return CmdViewType.ThreeD;
			case 5:
				return CmdViewType.Schedule;
			case 6:
				return CmdViewType.DrawingSheet;
			case 7:
			case 8:
			case 9:
				break;
			case 10:
				return CmdViewType.DraftingView;
			case 11:
				return CmdViewType.Legend;
			default:
                switch ((int)viewType)
				{
				case 115:
					return CmdViewType.EngineeringPlan;
				case 116:
					return CmdViewType.AreaPlan;
				case 117:
					return CmdViewType.Section;
				case 118:
					if (view is ViewSection)
					{
						return CmdViewType.Section;
					}
					return CmdViewType.FloorPlan;
				}
				break;
			}
			return CmdViewType.Other;
		}

		public static List<Autodesk.Revit.DB.View> FliterViews(UIApplication app)
		{
			Document document = app.ActiveUIDocument.Document;
			List<Autodesk.Revit.DB.View> list = new List<Autodesk.Revit.DB.View>();
			FilteredElementIterator elementIterator = new FilteredElementCollector(document).OfClass(typeof(Autodesk.Revit.DB.View)).GetElementIterator();
			elementIterator.Reset();
			while (elementIterator.MoveNext())
			{
				Element element = elementIterator.Current;
				Autodesk.Revit.DB.View view = element as Autodesk.Revit.DB.View;
				if (view != null && !view.IsTemplate && (1 == (int)view.ViewType || 2 == (int)view.ViewType || 116 == (int)view.ViewType || 115 == (int)view.ViewType || 4 == (int)view.ViewType || 3 == (int)view.ViewType || 117 == (int)view.ViewType || 10 == (int)view.ViewType || 5 == (int)view.ViewType || 11 == (int)view.ViewType || 6 == (int)view.ViewType))
				{
					list.Add(view);
				}
			}
			return list;
		}

		public static List<Autodesk.Revit.DB.View> FliterViews(ExternalCommandData cmdData)
		{
			return SwitchView.FliterViews(cmdData.Application);
		}

		public static List<Autodesk.Revit.DB.View> GetUsableViews(List<Autodesk.Revit.DB.View> views, CmdViewType types)
		{
			List<Autodesk.Revit.DB.View> list = new List<Autodesk.Revit.DB.View>();
			if ((CmdViewType.EngineeringPlan & types) != CmdViewType.Other)
			{
				foreach (Autodesk.Revit.DB.View view in views)
				{
					if (115 == (int)view.ViewType)
					{
						list.Add(view);
					}
				}
			}
			if ((CmdViewType.FloorPlan & types) != CmdViewType.Other)
			{
				foreach (Autodesk.Revit.DB.View view2 in views)
				{
					if (1 == (int)view2.ViewType)
					{
						list.Add(view2);
					}
				}
			}
			if ((CmdViewType.CeilingPlan & types) != CmdViewType.Other)
			{
				foreach (Autodesk.Revit.DB.View view3 in views)
				{
					if (2 == (int)view3.ViewType)
					{
						list.Add(view3);
					}
				}
			}
			if ((CmdViewType.ThreeD & types) != CmdViewType.Other)
			{
				foreach (Autodesk.Revit.DB.View view4 in views)
				{
					if (4 == (int)view4.ViewType)
					{
						list.Add(view4);
					}
				}
			}
			if ((CmdViewType.Elevation & types) != CmdViewType.Other)
			{
				foreach (Autodesk.Revit.DB.View view5 in views)
				{
					if (3 == (int)view5.ViewType)
					{
						list.Add(view5);
					}
				}
			}
			if ((CmdViewType.Section & types) != CmdViewType.Other)
			{
				foreach (Autodesk.Revit.DB.View view6 in views)
				{
					if (117 == (int)view6.ViewType)
					{
						list.Add(view6);
					}
				}
			}
			if ((CmdViewType.AreaPlan & types) != CmdViewType.Other)
			{
				foreach (Autodesk.Revit.DB.View view7 in views)
				{
					if (116 == (int)view7.ViewType)
					{
						list.Add(view7);
					}
				}
			}
			if ((CmdViewType.DraftingView & types) != CmdViewType.Other)
			{
				foreach (Autodesk.Revit.DB.View view8 in views)
				{
					if (10 == (int)view8.ViewType)
					{
						list.Add(view8);
					}
				}
			}
			if ((CmdViewType.Schedule & types) != CmdViewType.Other)
			{
				foreach (Autodesk.Revit.DB.View view9 in views)
				{
					if (5 == (int)view9.ViewType)
					{
						list.Add(view9);
					}
				}
			}
			if ((CmdViewType.Legend & types) != CmdViewType.Other)
			{
				foreach (Autodesk.Revit.DB.View view10 in views)
				{
					if (11 == (int)view10.ViewType)
					{
						list.Add(view10);
					}
				}
			}
			if ((CmdViewType.DrawingSheet & types) != CmdViewType.Other)
			{
				foreach (Autodesk.Revit.DB.View view11 in views)
				{
					if (6 == (int)view11.ViewType)
					{
						list.Add(view11);
					}
				}
			}
			return list;
		}

		private static string GetAreaPlanViewName(AreaPlanType types, Element inputElement, Autodesk.Revit.DB.View view)
		{
			ViewFamilyType viewFamilyType = inputElement as ViewFamilyType;
			switch (types)
			{
			case AreaPlanType.TotalArea:
				if ((view as ViewPlan).AreaScheme.Name.Contains("总建筑面积"))
				{
					return viewFamilyType.Name + "：" + RevitVersionFuncs.GetViewName(view);
				}
				break;
			case AreaPlanType.CivilAirDefenseArea:
				if ((view as ViewPlan).AreaScheme.Name.Contains("人防分区"))
				{
					return viewFamilyType.Name + "：" + RevitVersionFuncs.GetViewName(view);
				}
				break;
			case AreaPlanType.FireCompartmentArea:
				if ((view as ViewPlan).AreaScheme.Name.Contains("防火分区"))
				{
					return viewFamilyType.Name + "：" + RevitVersionFuncs.GetViewName(view);
				}
				break;
			case AreaPlanType.NetArea:
				if ((view as ViewPlan).AreaScheme.Name.Contains("净面积"))
				{
					return viewFamilyType.Name + "：" + RevitVersionFuncs.GetViewName(view);
				}
				break;
			}
			return null;
		}
	}
}
